/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)

#include <trace_log.h>
#include "umc_avs_dec_decompressor.h"
#include "umc_avs_picture_header.h"
#include "umc_avs_mb_info.h"
#include "umc_avs_dec_tables.h"

namespace UMC
{

void AVSDecompressor::ReconstructIMacroBlocksRow(void)
{
    MbMax = m_recCtx.MbIndex + m_recCtx.MbWidth;

    // we can use MbIndex from reconstructing context only
    MbIndex = m_recCtx.MbIndex;

    // set coeffs buffers
    m_pReadCoeffs = m_recCtx.m_pCoeffs;

    PrepareNeighbours(&m_recCtx);
    PrepareReconstruction(true);

    do
    {
        WRITE_TRACE_LOG_MB_TITLE(_rec_tst, MbIndex, m_recCtx.MbWidth, m_recCtx.MbHeight, 0 == m_recCtx.m_pPicHeader->progressive_frame);

        // reconstruct next macroblock
        ReconstructIMacroBlock();

        MbIndex += 1;
        AdvanceNeighbours();
        AdvanceReconstruction();

    } while (MbIndex < MbMax);

    // update context
    FinalizeReconstruction();

} // void AVSDecompressor::ReconstructIMacroBlocksRow(void)

void AVSDecompressor::ReconstructIMacroBlock(void)
{
    Ipp32u chromaQP;
    Ipp32s edge_type = 0;

    // prepare macroblock's absent block edges variable
    edge_type |= (m_pMbInfoLeft) ?
                 (0) : (IPPVC_LEFT_EDGE);
    edge_type |= (m_pMbInfoTop) ?
                 (0) : (IPPVC_TOP_EDGE);
    edge_type |= ((m_recCtx.MbY + 1) * m_recCtx.MbWidth - 1 != MbIndex) ?
                 (0) : (IPPVC_TOP_RIGHT_EDGE);

    WRITE_TRACE_LOG(_rec_tst, "CurrentQP", m_pMbInfo->QP);

    // reconstruct luminance blocks
    ippiReconstructLumaIntra_AVS_16s8u_C1R((Ipp16s **) &m_pReadCoeffs,
                                           m_recCtx.m_pPlanes8u[0],
                                           m_recCtx.m_iPitch,
                                           m_pMbInfo->IntraLumaPredMode,
                                           m_pMbInfo->NumCoeffs,
                                           m_pMbInfo->MbCBP,
                                           m_pMbInfo->QP,
                                           edge_type);

    WRITE_TRACE_LOG_BYTE_BLOCK(_rec_tst, "Y block", m_recCtx.m_pPlanes8u[0], m_recCtx.m_iPitch, 16, 16);

    // reconstruct chrominance blocks
    chromaQP = AVSChromaQPTable[m_pMbInfo->QP];
    WRITE_TRACE_LOG(_rec_tst, "chromaQP", chromaQP);
    ippiReconstructChromaIntra_AVS_16s8u_C1R((Ipp16s **) &m_pReadCoeffs,
                                             m_recCtx.m_pPlanes8u[1],
                                             m_recCtx.m_pPlanes8u[2],
                                             m_recCtx.m_iPitch,
                                             m_pMbInfo->IntraChromaPredMode[0],
                                             m_pMbInfo->NumCoeffs + 4,
                                             m_pMbInfo->MbCBP >> 4,
                                             chromaQP,
                                             edge_type);

    WRITE_TRACE_LOG_BYTE_BLOCK(_rec_tst, "U block", m_recCtx.m_pPlanes8u[1], m_recCtx.m_iPitch, 8, 8);
    WRITE_TRACE_LOG_BYTE_BLOCK(_rec_tst, "V block", m_recCtx.m_pPlanes8u[2], m_recCtx.m_iPitch, 8, 8);

} // void AVSDecompressor::ReconstructIMacroBlock(void)

} // namespace UMC

#endif // defined(UMC_ENABLE_AVS_VIDEO_DECODER)
